﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using Microsoft.SharePoint;
using PS.Practices.Provisioner.Provisioner.Util;
using PS.Practices.SiteBuilder.Features.Schema;
using PS.Practices.Util;
using PS.Practices.Provisioner.Provisioner;

namespace PS.Practices.Provisioner.ProvisionerUI
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class ProvisionerUI : SPItemEventReceiver
    {
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            base.ItemUpdated(properties);

            ProvisionWeb(properties);
        }

        /// <summary>
        /// An item has been updated
        /// </summary>
        public override void ItemAdded(SPItemEventProperties properties)
        {
            base.ItemAdded(properties);

            ProvisionWeb(properties);
        }

        private void ProvisionWeb(SPItemEventProperties properties)
        {
            SPListItem spListItem = properties.ListItem;
            SPList spList = properties.List;
            Dictionary<string, object> props = new Dictionary<string, object>();

            //Hydrate the properties dictionary.  Check for existing items before writing
            foreach (SPField field in spListItem.ContentType.Fields)
            {
                object value = null;
                props.TryGetValue(field.InternalName, out value);
                if(value == null)
                    props.Add(field.InternalName, PS.Practices.Provisioner.Util.ListUtil.TryGetListItemProperty(spListItem, field.InternalName));
            }

            //Provision the new web
            ProvisionerAbstract prov = new ProvisionerImplementation(properties.WebUrl, spListItem.ContentType.Name, props);
            var i = new Interpreter();
            i.ProvisionWeb(prov);
        }
    }


    public class ProvisionerImplementation : ProvisionerAbstract
    {
        public ProvisionerImplementation(string targetWebUrl, string galleryItemIdentifier, Dictionary<string, object> properties) : base(targetWebUrl, galleryItemIdentifier, properties)
        {
        }

        public override SPListItem LocateGalleryProvisionerItem(string identifier)
        {
            using(SPSite site = new SPSite(this.TargetWebUrl))
            {
                using(SPWeb web = site.OpenWeb())
                {
                    var cTypeName = identifier;
                    var provScriptList = web.Lists["Provisioner Scripts"];
                    SPListItem retItem = null;

                    var query = new SPQuery
                    {
                        Query =
                            String.Format(
                            "<Where><Eq><FieldRef Name='ContentType0'/><Value Type='Text'>{0}</Value></Eq></Where>",
                            cTypeName),
                        RowLimit = Constants.SpQueryRowLimit
                    };

                    SPListItemCollection myItems = provScriptList.GetItems(query);

                    if (myItems.Count > 0)
                    {
                        retItem = myItems[0];
                    }
                    else
                    {
                        throw new Exception("Could not locate script associated with content type " + GalleryItemIdentifier);
                    }

                    return retItem;
                }
            }
        }
    }

}
